package cn.apelx.shardingjdbc.algorithm;

import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;

import java.util.Collection;

/**
 * 自定义分片算法 - 分表
 * 看sharding源码，接口继承树:
 * ShardingSphereAlgorithm extends TypedSPI
 * --> ShardingAlgorithm
 * ----> StandardShardingAlgorithm
 * ----> ComplexKeysShardingAlgorithm
 * ----> HintShardingAlgorithm
 * <p>
 * 这里我使用标准的,配置文件里配置的策略也是标准的,只需要根据一个字段来分片
 * 多个字段分片实现ComplexKeysShardingAlgorithm
 * 不需要数据库字段分片实现HintShardingAlgorithm
 *
 * @author apelx
 * @since 2022-05-15
 */
public class CustomerAlgorithmTable implements StandardShardingAlgorithm<String> {

    /**
     * Initialize algorithm.
     */
    @Override
    public void init() {
    }

    /**
     * remark后面的数字为偶数去1号表,奇数去2号表
     * Sharding.
     *
     * @param availableTargetNames available data sources or table names 表名 customer_algorithm_1, customer_algorithm_2
     * @param shardingValue        sharding value
     * @return sharding result for data source or table name
     */
    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<String> shardingValue) {
        String columnName = shardingValue.getColumnName();
        String value = shardingValue.getValue();

        int index = Integer.parseInt(value.replace("remark", ""));
        index = index % 2;

        return availableTargetNames.toArray(new String[]{})[index];
    }

    /**
     * Sharding.
     *
     * @param availableTargetNames available data sources or table names
     * @param shardingValue        sharding value
     * @return sharding results for data sources or table names
     */
    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<String> shardingValue) {
        System.err.println("table: range do sharding...........");
        return availableTargetNames;
    }


    /**
     * Get type.
     *
     * @return type
     */
    @Override
    public String getType() {
        return "CLASS_BASED";
    }
}
